home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / X / fonts / scalable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.7 KB  |  330 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * scalable.c:
  19.  *  
  20.  * This file contains a few simple examples of using scalable fonts
  21.  * which were new to X11R5.  There are now two types of fonts:  bitmap
  22.  * fonts and "derived instances of scalable fonts".  Note that for a
  23.  * particular font specification it's not possible to determine whether
  24.  * the font actually displayed is a bitmap font or a derived instance of
  25.  * a scalable font.  
  26.  * 
  27.  * In a list of fonts, the name string of a scalable font will have a `0'
  28.  * in the PIXEL_SIZE, POINT_SIZE, and AVERAGE_WIDTH fields.
  29.  * 
  30.  * When you specify a font name with wildcards, for scalable fonts, you
  31.  * must provide a "well-formed" name.  A "well-formed" name is one in
  32.  * which you specify all 14 hyphens in the name string.  To choose a
  33.  * scalable font, put `0' in the PIXEL_SIZE, POINT_SIZE, and
  34.  * AVERAGE_WIDTH fields.  For example, 
  35.  * 
  36.  *         "-*-helvetica-medium-r-*-*-0-0-*-*-*-0-*-*"
  37.  * 
  38.  * is a "well-formed" name.  A name that doesn't contain all 14 hyphens,
  39.  * like:
  40.  * 
  41.  *         "-*-helvetica-medium-r-*"
  42.  * 
  43.  * is not.
  44.  * 
  45.  * The source file includes an example of using scalable fonts, and some
  46.  * utility functions to help select a scalable font, determine whether a
  47.  * font specification is "well-formed", and a few others.
  48.  * 
  49.  * See the comments in the source for more information.
  50.  * 
  51.  * See also, chapter 2 of the O'Reilly book:  "Programmer's Supplement
  52.  * for Release 5 of the X Window System, Version 11", by David Flanagan.
  53.  * 
  54.  */
  55. #include <stdlib.h>
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include <X11/Xlib.h>
  59. #include <X11/Xutil.h>
  60.  
  61. static Bool IsScalableFont( const char * );
  62. static XFontStruct *LoadQueryScalableFont( Display *, const int,
  63.                    const char *, const unsigned int );
  64. static void FontQueryExamples( Display * );
  65. static void drawWindow( Display *, Window, GC,
  66.                XFontStruct *[], const unsigned int, const unsigned int );
  67.  
  68. main(void)
  69. {
  70.   Display *dpy;
  71.   Window wind, rwin;
  72.   int scr;
  73.   unsigned int keep_going = 1;
  74.   XEvent ev;
  75.   unsigned int i;
  76.   const unsigned int MAXFONTS = 32;
  77.   XFontStruct *courier_s[MAXFONTS];
  78.   GC gc;
  79.  
  80.   XWMHints    wmhints;
  81.   XSizeHints  wmsizehints;
  82.   XClassHint  classhint;
  83.   XColor dsg, edsg, ylo, eylo, dbl, edbl;
  84.  
  85.   dpy = XOpenDisplay("");
  86.   scr = DefaultScreen(dpy);
  87.   rwin = RootWindow(dpy, scr);
  88.  
  89.  
  90.   wind = XCreateSimpleWindow( dpy, rwin, 0, 0, 512, 512, 2,
  91.                  BlackPixel(dpy,scr), WhitePixel(dpy,scr));
  92.  
  93.   classhint.res_name = "LEFT or RIGHT Mouse to Change Font Size";
  94.   classhint.res_class = "Scalable Fonts";
  95.   XSetClassHint(dpy, wind, &classhint);
  96.  
  97.   wmhints.input = True;
  98.   wmhints.flags = InputHint;
  99.   XSetWMHints(dpy, wind, &wmhints);
  100.  
  101.   wmsizehints.x = 100;
  102.   wmsizehints.y = 100;
  103.   wmsizehints.width = 100;
  104.   wmsizehints.height = 100;
  105.   wmsizehints.flags = USPosition | USSize;
  106.   XSetWMNormalHints(dpy, wind, &wmsizehints);
  107.  
  108.   gc = XCreateGC( dpy, wind, (Mask)0, NULL );
  109.   XCopyGC( dpy, XDefaultGC(dpy,scr), (Mask)(~0) , gc );
  110.  
  111.   XAllocNamedColor( dpy, DefaultColormap(dpy,scr), "darkslategray",
  112.            &dsg, &edsg );
  113.  
  114.   XAllocNamedColor( dpy, DefaultColormap(dpy,scr), "yellow", &ylo, &eylo );
  115.  
  116.   XAllocNamedColor( dpy, DefaultColormap(dpy,scr), "blue", &dbl, &edbl );
  117.  
  118.   XSetForeground( dpy, gc, ylo.pixel );
  119.   XSetBackground( dpy, gc, dsg.pixel );
  120.   XSetWindowBackground( dpy, wind, dsg.pixel );
  121.  
  122.   for( i = 0; i < MAXFONTS; i++ ){
  123.     courier_s[i] = LoadQueryScalableFont( dpy, scr,
  124.                      "-*-helvetica-medium-r-*-*-0-0-*-*-*-0-*-*",
  125.                      10*(i+6) );
  126.   }
  127.   
  128.   XSelectInput( dpy, wind, ButtonPressMask|KeyPressMask|ExposureMask);
  129.   XMapWindow( dpy, wind );
  130.  
  131.   do { 
  132.     XNextEvent( dpy, &ev );
  133.     switch( ev.type )
  134.     {
  135.     case Expose:
  136.       while( XCheckTypedEvent(dpy, Expose, &ev) );
  137.       i = 0;
  138.       drawWindow( dpy, wind, gc, courier_s, i, MAXFONTS );
  139.       break;
  140.  
  141.     case KeyPress:
  142.       XCloseDisplay(dpy);
  143.       keep_going = 0;
  144.       break;
  145.  
  146.     case ButtonPress:
  147.       if( ev.xbutton.button == Button1 )
  148.     i++;
  149.       else if( ev.xbutton.button == Button3 )
  150.     i--;
  151.       else if( ev.xbutton.button == Button2 )
  152.     i = 0;
  153.       drawWindow( dpy, wind, gc, courier_s, i, MAXFONTS );
  154.       break;
  155.  
  156.     default:
  157.       break;
  158.     }
  159.   } while( keep_going );
  160.  
  161.   XCloseDisplay( dpy );
  162.   exit(0);
  163. }
  164.  
  165. static void drawWindow( Display *dpy, Window wind, GC gc,
  166.                XFontStruct *courier_s[], const unsigned int i, const unsigned int MAXFONTS )
  167. {
  168.   char cbuf[64];
  169.   char lbuf[256];
  170.  
  171.   XClearWindow( dpy, wind );
  172.   XSetFont( dpy, gc, courier_s[i%MAXFONTS]->fid );
  173.   XDrawString( dpy, wind, gc, 10, 100, "The Quick Brown Fox", 19 );
  174.   sprintf(cbuf, "%u", ((i%MAXFONTS)+6));
  175.   strcpy(lbuf, "Point size is:  ");
  176.   strcat(lbuf, cbuf);
  177.   XDrawString( dpy, wind, gc, 10, 200, lbuf, (int)strlen(lbuf) );
  178. }
  179.  
  180.  
  181. /* This routine returns True if the passed name is a well-formed XLFD style
  182.    font name with a pixel size, point size, and average width
  183.    (fields 7, 8, and 12) of "0". */
  184. static Bool IsScalableFont( const char *name )
  185. {
  186.   unsigned int i, field;
  187.  
  188.   if( (name == NULL) || (name[0] != '-') ) return( False );
  189.  
  190.   for( i = field = 0; name[i] != '\0'; i++ ){
  191.     if( name[i] == '-' ) {
  192.       field++;
  193.       if( (field == 7 ) || (field == 8) || (field == 12) )
  194.     if( (name[i+1] != '\0') || (name[i+2] != '-') )
  195.       return( False );
  196.     }
  197.   }
  198.   if( field != 14 ) return( False );
  199.   else return( True );
  200. }
  201.  
  202. /* This routine is passed a scalable font name and a point size.  It
  203.    returns an XFontStruct for the given font scaled to the specified
  204.    size and the exact resolution of the screen.  The font name is assumed
  205.    to be a well-formed XLFD name, and to have pixel size, point size,
  206.    and average width fields of "0" and arbitrary x-resolution and y-resolution
  207.    fields.  Size is specified in tenths of points.  Returns NULL if the
  208.    name is malformed or no such font exists. */
  209.  
  210. static XFontStruct *LoadQueryScalableFont( Display *dpy, const int screen,
  211.                     const char *name, const unsigned int size )
  212. {
  213.   unsigned int i, j, field;
  214.   char newname[500];
  215.   unsigned int res_x, res_y;  /* rez values for this screen */
  216.  
  217.   /* catch obvious errors */
  218.   if( (name == NULL) || (name[0] != '-') ) return( NULL );
  219.  
  220.   /* calculate our screen rez in dpi.  25.4mm == 1 inch */
  221.   res_x = (unsigned int)((float)DisplayWidth( dpy, screen )/( (float)DisplayWidthMM(dpy, screen)/(float)25.4));
  222.   res_y = (unsigned int)((float)DisplayHeight( dpy, screen )/( (float)DisplayHeightMM(dpy, screen)/(float)25.4));
  223.  
  224.   /* copy the font name, changing the scalable fields as we do so */
  225.   for( i = j = field = 0; name[i] != '\0' && field <= 14; i++ ) {
  226.     newname[j++] = name[i];
  227.     if( name[i] == '-' ) {
  228.       field++;
  229.       switch( field ) {
  230.       case 7:  /* pixel size */
  231.       case 12:  /* average width */
  232.     /* change from "-0-" to "-*-" */
  233.     newname[j] = '*';
  234.     j++;
  235.     if( name[i+1] != '\0' ) i++;
  236.       break;
  237.       case 8:  /* point size */
  238.     /* change from "-0-" to "-<size>-" */
  239.     sprintf(&newname[j], "%d", size );
  240.     while( newname[j] != '\0' ) j++;
  241.     if( name[i+1] != '\0' ) i++;
  242.     break;
  243.       case 9: /* x-res */
  244.       case 10: /* y-res */
  245.     /* change from an unspec rez to res_x or res_y */
  246.     sprintf(&newname[j], "%d", (field == 9) ? res_x : res_y );
  247.     while( newname[j] != '\0' ) j++;
  248.     while( (name[i+1] != '-') && (name[i+1] != '\0') ) i++;
  249.     break;
  250.       }
  251.     }
  252.   }
  253.   newname[j] = '\0';
  254.  
  255.   /* if there aren't 14 hyphens, it isn't a well formed name */
  256.   if( field != 14 ) return( NULL );
  257.  
  258.   return( XLoadQueryFont( dpy, newname ) );
  259. }
  260.  
  261. static void FontQueryExamples( Display *dpy )
  262. {
  263.   unsigned int i;
  264.   unsigned int count = 0;
  265.   Font font;
  266.   char **fonts;
  267.  
  268.   /* List all Latin-1 fonts.  Returned names of scalable fonts will have "0"
  269.    * for pixel size, point size, and average width */
  270.   fonts = XListFonts( dpy, "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1", 1000,
  271.              (int *)&count );
  272.   /*
  273.      printf( "All Latin-1 fonts:\n" );
  274.      for( i = 0; i < count; i++ )
  275.      printf( "%s\n", fonts[i] );
  276.      */
  277.  
  278.   /* List all scalable courier fonts.  Non-scalable fonts will
  279.      not be listed */
  280.   printf( "\nAll scalable Courier fonts:\n" );
  281.   fonts = XListFonts( dpy, "-*-courier-*-*-*-*-0-0-*-*-*-0-*-*", 200,
  282.              (int *)&count );
  283.   for( i = 0; i < count; i++ )
  284.     printf( "%s\n", fonts[i] );
  285.  
  286.   /* Load a 12-point bold helvetica font defined at a 100x100 dpi
  287.      resolution.  The actual font loaded might be a derived instance
  288.      of a scalable font, or it might be a bitmap font-- there is no way
  289.      to distinguish between them.     */
  290.  
  291.   font = XLoadFont( dpy,
  292.            "-*-helvetica-bold-r-*-*-*-120-100-100-*-*-iso8859-1" );
  293.  
  294.   /* Load a 20 pixel high helvetica font defined at 100x100 dpi */
  295.   font = XLoadFont( dpy,
  296.            "-*-helvetica-medium-r-*-*-20-*-100-100-*-*-iso8859-1" );
  297.   /* load all 13-point Latin-1 Helvetica fonts defined at a 106x7 dpi
  298.      resolution.  This pattern will match derived instances of scalable
  299.      fonts, and will probably only match derived instances of scalable
  300.      fonts, because there are not likely to be bitmap fonts defined at this
  301.      particular size and resolution */
  302.  
  303.   printf( "\nAll 13-point Helvetica fonts at 106x97 resolution:\n" );
  304.   fonts = XListFonts( dpy, "-*-helvetica-*-*-*-*-*-130-106-97-*-*-iso8859-1",
  305.              50, (int *)&count );
  306.   for( i = 0; i < count; i++ )
  307.     printf( "%s\n", fonts[i] );
  308.  
  309.   /* List 15-point bold oblique Helvetica fonts.  Derived instances of
  310.      scalable fonts will probably not be included in the list because
  311.      the pattern does not have all 14 fields. */
  312.  
  313.   printf( "\nAll 15-point Helvetica bold oblique fonts:\n" );
  314.   fonts = XListFonts( dpy, "-*-helvetica-bold-o-*-*-*-150-*", 50, (int *)&count );
  315.   for( i = 0; i < count; i++ )
  316.     printf( "%s\n", fonts[i] );
  317.  
  318.   /* List all 17-point, 17-pixel bold oblique Helvetica fonts defined
  319.      at 100x100dpi.  This pattern will not match any derived instances
  320.      of scalable fonts (nor any font) because a 17 point font at 100dpi
  321.      is not 17 pixels high. */
  322.  
  323.   printf( "\nAll 17-point Helvetica bold oblique fonts at 100x100 dpi:\n" );
  324.   fonts = XListFonts( dpy,
  325.              "-*-helvetica-bold-o-*-*-17-170-100-100-*-*-iso8859-1",
  326.              50, (int *)&count );
  327.   for( i = 0; i < count; i++ )
  328.     printf( "%s\n", fonts[i] );
  329. }
  330.